package datastruct.queue;

import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 循环队列(数组)
 * 条件判断：(front：第一个元素；   rear：最后一个元素的后一个位置)
 *  队列已满：front == (rear + 1) % maxSize
 *  队列为空：front == rear
 *  元素个数：(rear - front + maxSize) % maxSize
 */
public class CircularQueue<T> {
    private Object[] queue;
    private int front;  // 队头指针(指向：第一个元素)
    private int rear;   // 队尾指针(指向：最后一个元素的后一个位置)
    private int maxSize;

    public CircularQueue(int maxSize) {
        this.maxSize = maxSize;
        this.queue = new Object[maxSize];
    }

    /**
     * 添加元素
     */
    public void add(T e) {
        isFull();
        this.queue[rear] = e;
        rear = (rear + 1) % maxSize;
    }

    /**
     * 弹出第一个元素
     */
    public T remove() {
        T e = this.element();
        front = (front + 1) % maxSize;
        return e;
    }

    /**
     * 查看第一个元素
     */
    public T element() {
        isEmpty();
        return (T) this.queue[front];
    }

    /**
     * 判断队列已满
     */
    private void isFull() {
        if (front == (rear + 1) % maxSize) {
            throw new RuntimeException("队列已满");
        }
    }

    /**
     * 判断队列为空
     */
    private void isEmpty() {
        if (front == rear) {
            throw new RuntimeException("队列为空");
        }
    }

    @Override
    public String toString() {
        int size = (rear - front + maxSize) % maxSize;
        return IntStream.range(front, front + size)
                .mapToObj(i -> String.valueOf(queue[i % maxSize]))
                .collect(Collectors.joining(", ", "[", "]"));
    }
}
